package com.dream.service.recommender.base.impl;

import com.dream.common.model.response.BaseResponse;
import com.dream.service.procure.domain.enums.StockStatus;
import com.dream.service.product.domain.entity.SpuBase;
import com.dream.service.recommender.toolkits.utils.StringUtils;
import com.dream.service.wrapper.api.ProductWrapperService;
import com.dream.service.wrapper.domain.entity.SPUData;
import com.dream.service.recommender.api.RecommenderService;
import com.dream.service.recommender.base.compare.WeightComparator;
import com.dream.service.recommender.domain.response.RecommenderData;
import com.dream.service.recommender.domain.response.RecommenderItem;
import com.dream.service.recommender.domain.response.RecommenderSku;
import com.dream.service.wrapper.domain.request.SPUDataRequest;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * Created by zhiji on 2016/04/25.
 */
public abstract class BaseRecommenderService implements RecommenderService {

    /**
     * 商品基础信息服务
     */
    private ProductWrapperService productWrapperService;

    public ProductWrapperService getProductWrapperService() {
        return productWrapperService;
    }

    @Autowired
    public void setProductWrapperService(ProductWrapperService productWrapperService) {
        this.productWrapperService = productWrapperService;
    }

    /**
     * 获取基础信息
     *
     * @param spus
     * @return
     */
    public Map<Long, SPUData> getBaseInfo(Collection<Long> spus,Integer cityId) {
        return getBaseInfo(spus, true, false,cityId);
    }

    /**
     * 获取基本信息
     *
     * @param spus
     * @param returnPrice
     * @param returnStock
     * @return
     */
    public Map<Long, SPUData> getBaseInfo(Collection<Long> spus, boolean returnPrice, boolean returnStock,Integer cityId) {
        Map<Long, SPUData> result = null;
        try {
            if (productWrapperService == null) {
                System.out.println(888);
                return null;
            }
            Set<Long> _spus = new HashSet<Long>(spus);
            SPUDataRequest spuDataRequest = new SPUDataRequest();
            spuDataRequest.setSpus(_spus);
            spuDataRequest.setReturnPrice(returnPrice);
            spuDataRequest.setReturnStockStatus(returnStock);
            spuDataRequest.setCity_id(cityId==null?0:cityId);
            BaseResponse<Map<Long, SPUData>> spuDataResponse = productWrapperService.getSPUData(spuDataRequest);
            if (spuDataResponse.isSuccess()) {
                result = spuDataResponse.getResult();
            } else {

                System.out.println("Invoke Product Wrapper Service Fail." + spuDataResponse.getError_msg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            /*logger.error("get base info error,",e);*/
        }
        return result;
    }

    /**
     * 构建数据
     *
     * @param response
     * @param success
     * @param error_code
     * @param error_message
     * @param recommenderData
     * @return
     */
    public BaseResponse<RecommenderData> buildResult(BaseResponse<RecommenderData> response, boolean success, int error_code, String error_message, RecommenderData recommenderData) {
        return buildResult(response, success, error_code, error_message, recommenderData, 0, 0);
    }

    /**
     * 构建数据最终结果
     *
     * @param response
     * @param success
     * @param error_code
     * @param error_message
     * @param recommenderData
     * @param start
     * @param end
     * @return
     */
    public BaseResponse<RecommenderData> buildResult(BaseResponse<RecommenderData> response, boolean success, int error_code, String error_message, RecommenderData recommenderData, int start, int end) {
        if (response == null) {
            response = new BaseResponse<RecommenderData>();
        }
        response.setSuccess(success);
        response.setError_code(error_code);
        response.setError_msg(error_message);
        if (recommenderData != null) {
            if (end < start) {
                response.setResult(new RecommenderData());
                return response;
            }
            if (end <= 0) {
                response.setResult(recommenderData);
//                System.out.println(end + JSONObject.toJSONString(recommenderData));
            } else {
                if (recommenderData != null && !StringUtils.isEmpty(recommenderData.getList())) {
                    int _end = Math.min(recommenderData.getList().size(), end);
                    if (_end >= start) {
                        recommenderData.setList(recommenderData.getList().subList(start, _end));
                        response.setResult(recommenderData);
                    } else {
                        recommenderData.setList(new ArrayList<RecommenderItem>());
                    }
                }
            }
        }
        return response;
    }

    /**
     * 库存过滤
     *
     * @param recommenderData
     * @param spuDataMap
     * @return
     */
    public Set<Long> filterByStock(RecommenderData recommenderData, Map<Long, SPUData> spuDataMap) {
        if (recommenderData == null || StringUtils.isEmpty(recommenderData.getList()) || spuDataMap == null || spuDataMap.isEmpty()) {
            return null;
        }
        List<RecommenderItem> items = recommenderData.getList();
        Iterator<RecommenderItem> itemIterator = items.iterator();
        Set<Long> nostockSpu = new HashSet<Long>();
        while (itemIterator.hasNext()) {
            RecommenderItem recommenderItem = itemIterator.next();
            if (recommenderItem instanceof RecommenderSku) {
                RecommenderSku recommenderSku = (RecommenderSku) recommenderItem;
                Long spu = recommenderSku.getSpu();
                SPUData spuData = spuDataMap.get(spu);
                if (spuData == null) {
                    itemIterator.remove();
                    nostockSpu.add(spu);
                    continue;
                }
                SpuBase spuBase = spuData.getSpuBase();
                if (spuBase.getIsPutOn() != 1 || spuBase.getStatus_code() != 100 || spuData.getStockStatus() != StockStatus.NO) {
                    itemIterator.remove();
                    nostockSpu.add(spu);
                }
            }
        }
        return nostockSpu;
    }

    /**
     * 穿插排序 (通过类目穿插)
     *
     * @param recommenderData
     * @param spuDataMap
     * @return
     */
    public RecommenderData SortAndRank(RecommenderData recommenderData, Map<Long, SPUData> spuDataMap) {
        if (recommenderData == null) {
            return recommenderData;
        }
        List<RecommenderSku> recommenderSkus = recommenderData.getList();
        if (StringUtils.isEmpty(recommenderSkus)) {
            return recommenderData;
        }
        Map<Integer, List<RecommenderSku>> categoryItems = new HashMap<Integer, List<RecommenderSku>>();
        for (RecommenderSku recommenderSku : recommenderSkus) {//根据cid重组spu
            long spu = recommenderSku.getSpu();
            SPUData spuData = spuDataMap.get(spu);
            if (spuData == null) {//是不是多余的判断?
                continue;
            }
            SpuBase spuBase = spuData.getSpuBase();
            List<RecommenderSku> relSkus = categoryItems.get(spuBase.getCategory_id());
            if (relSkus == null) {
                relSkus = new ArrayList<RecommenderSku>();
                categoryItems.put(spuBase.getCategory_id(), relSkus);
            }
            relSkus.add(recommenderSku);
        }
        List<RecommenderSku> sortRecommenderItems = new ArrayList<RecommenderSku>();
        boolean loop = true;
        do {
            List<RecommenderSku> subRecommenderItems = new ArrayList<RecommenderSku>(categoryItems.size());
            Iterator<Map.Entry<Integer, List<RecommenderSku>>> entryiterator = categoryItems.entrySet().iterator();
            while (entryiterator.hasNext()) {
                Map.Entry<Integer, List<RecommenderSku>> productentry = entryiterator.next();
                List<RecommenderSku> productList = productentry.getValue();
                if (StringUtils.isEmpty(productList)) {
                    entryiterator.remove();
                    continue;
                }
                RecommenderSku recommenderSku = productList.remove(0);
                subRecommenderItems.add(recommenderSku);
            }
            Collections.sort(subRecommenderItems, new WeightComparator());
            sortRecommenderItems.addAll(subRecommenderItems);
            if (categoryItems.isEmpty()) {
                loop = false;
            }
            if (categoryItems.size() == 1) {
                Set<Integer> keys = categoryItems.keySet();
                Iterator<Integer> keyiterator = keys.iterator();
                while (keyiterator.hasNext()) {
                    Integer catid = keyiterator.next();
                    sortRecommenderItems.addAll(categoryItems.get(catid));
                }
                loop = false;
            }
        } while (loop);
        recommenderData.setList(sortRecommenderItems);
        return recommenderData;
    }
}
